package com.xafc.demo.framework.utils;

import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.Date;
import java.util.Locale;

/**
 *
 */
public class UnixDateUtil {
    public static final String YYYYMMDD_DASH_PATTERN = "yyyy-MM-dd";
    public static final String YEAR_PATTERN = "yyyy";
    public static final String YYYYMMDD_PATTERN = "yyyyMMdd";
    public static final String YYYYMMDD_TIME_PATTERN = "yyyyMMdd HH:mm:ss";
    public static final String YYYYMMDD_TIMES_PATTERN = "yyyyMMdd HH:mm:ss.SSS";
    public static final Locale DEFAULT_LOCALE;
    public static final DateTimeZone DEFAULT_TIMEZONE;

    public UnixDateUtil() {
    }

    public static DateTimeFormatter getDateTimeFormatter(String pattern) {
        return DateTimeFormat.forPattern(pattern).withZone(DEFAULT_TIMEZONE).withLocale(DEFAULT_LOCALE);
    }

    public static String year(Date date) {
        return getDateTimeFormatter("yyyy").print(new DateTime(date));
    }

    public static String yyyyMMdd(Date date) {
        return getDateTimeFormatter("yyyyMMdd").print(new DateTime(date));
    }

    public static String yyyyMMddDash(Date date) {
        return getDateTimeFormatter("yyyy-MM-dd").print(new DateTime(date));
    }

    public static String yyyyMMddTime(Date date) {
        return getDateTimeFormatter("yyyyMMdd HH:mm:ss").print(new DateTime(date));
    }

    public static String yyyyMMddTimes(Date date) {
        return getDateTimeFormatter("yyyyMMdd HH:mm:ss.SSS").print(new DateTime(date));
    }

    public static DateTime year(String dateFormat) {
        return getDateTimeFormatter("yyyy").parseDateTime(dateFormat);
    }

    public static DateTime yyyyMMdd(String dateFormat) {
        return getDateTimeFormatter("yyyyMMdd").parseDateTime(dateFormat);
    }

    public static DateTime yyyyMMddDash(String dateFormat) {
        return getDateTimeFormatter("yyyy-MM-dd").parseDateTime(dateFormat);
    }

    public static DateTime yyyyMMddTime(String dateFormat) {
        return getDateTimeFormatter("yyyyMMdd HH:mm:ss").parseDateTime(dateFormat);
    }

    public static DateTime yyyyMMddTimes(String dateFormat) {
        return getDateTimeFormatter("yyyyMMdd HH:mm:ss.SSS").parseDateTime(dateFormat);
    }

    public static int unixTime() {
        return (int)(System.currentTimeMillis() / 1000L);
    }

    public static Date dateTime(int unix) {
        return new Date((long)unix * 1000L);
    }

    public static int unixTime(Date date) {
        return date == null ? 0 : (int)(date.getTime() / 1000L);
    }

    public static int unixTime(DateTime dateTime) {
        return dateTime == null ? 0 : (int)(dateTime.getMillis() / 1000L);
    }

    public static Pair<DateTime, DateTime> minMaxOfDay(DateTime time) {
        DateTime.Property millisOfDay = time.millisOfDay();
        DateTime maximumValue = millisOfDay.withMaximumValue();
        DateTime minimumValue = millisOfDay.withMinimumValue();
        return Pair.of(minimumValue, maximumValue);
    }

    public static Pair<Integer, Integer> unixMinMaxOfDay(DateTime time) {
        DateTime.Property millisOfDay = time.millisOfDay();
        DateTime maximumValue = millisOfDay.withMaximumValue();
        DateTime minimumValue = millisOfDay.withMinimumValue();
        return Pair.of(unixTime(minimumValue), unixTime(maximumValue));
    }

    public static Pair<DateTime, DateTime> minMaxOfMonth(DateTime month) {
        DateTime.Property monthOfYear = month.monthOfYear();
        DateTime maximumValue = monthOfYear.withMaximumValue();
        DateTime minimumValue = monthOfYear.withMinimumValue();
        return Pair.of(minimumValue, maximumValue);
    }

    public static Pair<Integer, Integer> unixMinMaxOfMonth(DateTime month) {
        DateTime.Property monthOfYear = month.monthOfYear();
        DateTime maximumValue = monthOfYear.withMaximumValue();
        DateTime minimumValue = monthOfYear.withMinimumValue();
        return Pair.of(unixTime(minimumValue), unixTime(maximumValue));
    }

    public static long unixTimeLong() {
        return System.currentTimeMillis() / 1000L;
    }

    static {
        DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
        DEFAULT_TIMEZONE = DateTimeZone.forOffsetHours(8);
    }
}

